﻿using System;
using Microsoft.Practices.Unity;
using SW.Lite.Infrastructure.Exception;
using SW.Lite.Infrastructure.Helpers;

namespace SW.Lite.Infrastructure.Service
{
    public class ServiceLocator
    {
        private static readonly ServiceLocator Locator = new ServiceLocator();
        private readonly UnityContainer _container = new UnityContainer();

        private ServiceLocator()
        {
            foreach (var component in ConfigHelper.Instance.Components)
            {
                var fromType = Type.GetType(component.Service);
                var toType = Type.GetType(component.Instance);

                if (fromType == null)
                    throw new CodeException(0x000023);

                if (toType == null)
                    throw new CodeException(0x000024);

                try
                {
                    _container.RegisterType(fromType, toType, component.Name);
                }
                catch (System.Exception ex)
                {
                    throw new CodeException(0x000025, "", ex);
                }
            }
        }

        public static ServiceLocator Instance
        {
            get { return Locator; }
        }

        public TInstance GetInstance<TInstance>()
        {
            return _container.Resolve<TInstance>();
        }

        public TInstance GetInstance<TInstance>(string name)
        {
            return _container.Resolve<TInstance>(name);
        }

        public void RegisterType<TService, TInstance>(string name)
            where TInstance : TService
        {
            _container.RegisterType<TService, TInstance>(name);
        }

        public void RegisterType(string name, Type serviceType, Type instanceType)
        {
            _container.RegisterType(serviceType, instanceType, name);
        }

        public void RegisterType<TService>(string name, Type instanceType)
        {
            _container.RegisterType(typeof(TService), instanceType, name);
        }

        public void RegisterInstance<TService>(string name, TService instance)
        {
            _container.RegisterInstance(name, instance);
        }
    }
}